﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using static HynuIOTA.Web.Filters.CacheDependencyKeys;

namespace HynuIOTA.Web.Filters
{
    public class OutPutCacheDependencyAttrbute : ActionFilterAttribute
    {
        /// <summary>
        /// 权限过滤上下文
        /// </summary>
        protected ActionExecutingContext FiterContext { get; set; }

        /// <summary>
        /// 请求区域名
        /// </summary>
        protected string AreaName { get; set; } = string.Empty;

        /// <summary>
        ///  请求Action方法名
        /// </summary>
        protected string ActionName { get; set; } = string.Empty;

        /// <summary>
        /// 请求控制器名
        /// </summary>
        protected string ControllerName { get; set; } = string.Empty;

        /// <summary>
        /// 请求方法名
        /// </summary>
        protected string Method { get; set; }

        /// <summary>
        /// 请求字符串
        /// </summary>
        protected string RequestUrl { get; set; }

        /// <summary>
        /// 初始化属性
        /// </summary>
        /// <param name="filterContext"></param>
        private void InitProperty(ActionExecutingContext filterContext)
        {
            this.FiterContext = filterContext;

            if (FiterContext.ActionDescriptor.ActionName != null)
                ActionName = FiterContext.ActionDescriptor.ActionName.ToLower();

            if (FiterContext.ActionDescriptor.ControllerDescriptor.ControllerName != null)
                ControllerName = FiterContext.ActionDescriptor.ControllerDescriptor.ControllerName.ToLower();

            if (FiterContext.HttpContext.Request.HttpMethod != null)
                Method = FiterContext.HttpContext.Request.HttpMethod.ToLower();

            RequestUrl = $"/{ControllerName}/{ActionName}";

            // 判断请求中是否存在区域
            if (filterContext.RouteData.DataTokens.ContainsKey("area"))
            {
                // 请求区域名称
                string strArea = (string)filterContext.RouteData.DataTokens["area"];

                // 拼接
                RequestUrl = strArea == null ? RequestUrl : $"/{strArea.ToLower()}{RequestUrl}";
            }
        }

        /// <summary>
        /// 输出缓存依赖字典
        /// </summary>
        public static Dictionary<string, string[]> OutPutCacheDependencyDictionary { get; set; } =
            new Dictionary<string, string[]>()
            {
                #region 首页

                // 首页缓存依赖项
                {"/home/index", new string[] {Global, News, Notice, Article}},
                // 首页底部
                {"/home/indexbottom", new string[] {Global, Config}},
                // 首页栏目
                {"/home/channelsnav", new string[] {Global, Channel}},

                #endregion

                #region 新闻栏目

                // 新闻栏目视图
                {"/home/newschannelview", new string[] {Global, Channel}},
                // 栏目列表
                {"/home/newschannel", new string[] {Global, Channel}},
                // 显示新闻
                {"/home/shownews", new string[] {Global, News}},
                // 新闻列表
                {"/home/news", new string[] {Global, News}},

                #endregion

                #region 通知

                // 通知列表
                {"/home/notices", new string[] {Global, Notice}},
                // 显示通知
                {"/home/shownotice", new string[] {Global, Notice}},

                #endregion

                #region 博客

                // 博客列表
                {"/blog/bloglist", new string[] {Global, Article}},
                // 获取标签列表
                {"/blogs/blog/gettags", new string[] {Global, Tag}},
                // 最新评论文章
                {"/blogs/blog/getnewcommentbloglist", new string[] {Global, Article}},
                // 标签博客列表
                {"/blogs/blog/tagbloglist", new string[] {Global, Article, Tag}},
                // 显示博客
                {"/blog/showblog", new string[] {Global, Article}}

                #endregion
            };

        //"/home/index", "/home/indexbottom", "/home/channelsnav", "/home/notices", "/home/newschannelview", "/home/shownotice", "/home/newschannel", "/home/shownews", "/home/news", "/blog/bloglist", "/blogs/blog/gettags", "/blogs/blog/getnewcommentbloglist", "/blogs/blog/tagbloglist", "/blog/showblog"
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            // 判断是否添加了输出缓存特性
            if (filterContext.ActionDescriptor.IsDefined(typeof(OutputCacheAttribute), false) == true)
            {
                InitProperty(filterContext);

                if (OutPutCacheDependencyDictionary.Keys.Contains(RequestUrl) == true)
                {
                    // 将缓存依赖添加至过滤器
                    filterContext.HttpContext.Response.AddCacheItemDependencies(OutPutCacheDependencyDictionary[RequestUrl]);
                }
            }
        }
    }

    // 缓存依赖项的KEY
    public static class CacheDependencyKeys
    {
        public static string[] CacheDependencyIndex { get; } = new[] {Global, News, Notice, Article, Channel, Config, Tag};

        public const string Global = "Global_Cache";

        public const string News = "News_Cache";

        public const string Notice = "Notice_Cache";

        public const string Article = "Article_Cache";

        public const string Channel = "Channel_Cache";

        public const string Config = "Config_Cache";

        public const string Tag = "Tag_Cache";
    }
}